<template>
  <div class="demo-view">
    <h1 class="page-title">全同态加密演示</h1>
    <p class="page-description">体验在加密数据上进行计算，无需解密原始数据。本演示使用SEAL库实现全同态加密操作。</p>
    
    <div class="demo-container">
      <!-- 左侧输入区 -->
      <div class="input-section">
        <h2>输入数据</h2>
        <div class="input-group">
          <label for="input-a">数值 A</label>
          <div class="input-with-icon">
            <input 
              type="number" 
              id="input-a" 
              v-model="inputA" 
              placeholder="输入第一个数值"
              :disabled="isEncrypted || isLoading"
            />
            <span class="lock-icon" v-if="isEncrypted">🔒</span>
          </div>
        </div>
        
        <div class="input-group">
          <label for="input-b">数值 B</label>
          <div class="input-with-icon">
            <input 
              type="number" 
              id="input-b" 
              v-model="inputB" 
              placeholder="输入第二个数值"
              :disabled="isEncrypted || isLoading"
            />
            <span class="lock-icon" v-if="isEncrypted">🔒</span>
          </div>
        </div>
        
        <div class="action-buttons">
          <button 
            class="btn btn-primary" 
            @click="encryptData" 
            :disabled="isEncrypted || !canEncrypt || isLoading"
          >
            {{ isLoading ? '处理中...' : '加密数据' }}
          </button>
          <button 
            class="btn btn-secondary" 
            @click="loadSampleData"
            :disabled="isEncrypted || isLoading"
          >
            加载示例数据
          </button>
          <button 
            class="btn btn-secondary" 
            @click="resetDemo"
            v-if="isEncrypted || hasResult"
            :disabled="isLoading"
          >
            重置演示
          </button>
        </div>
      </div>
      
      <!-- 中间计算区 -->
      <div class="computation-section">
        <h2>加密数据</h2>
        <div class="encrypted-data-container">
          <div class="encrypted-data" v-if="isEncrypted">
            <div class="data-label">加密数值 A:</div>
            <div class="data-value" :class="{ 'active': activeOperation === 'compare' && highlightA }">
              {{ encryptedA }}
            </div>
          </div>
          <div class="encrypted-data" v-if="isEncrypted">
            <div class="data-label">加密数值 B:</div>
            <div class="data-value" :class="{ 'active': activeOperation === 'compare' && highlightB }">
              {{ encryptedB }}
            </div>
          </div>
          <div class="placeholder-text" v-if="!isEncrypted">
            <p>请先输入数据并点击"加密数据"按钮</p>
          </div>
        </div>
        
        <div class="operation-buttons" v-if="isEncrypted">
          <button 
            class="operation-btn" 
            @click="performOperation('compare')"
            :class="{ 'active': activeOperation === 'compare' }"
            :disabled="isLoading"
          >
            比较大小
          </button>
          <button 
            class="operation-btn" 
            @click="performOperation('add')"
            :class="{ 'active': activeOperation === 'add' }"
            :disabled="isLoading"
          >
            加法运算
          </button>
          <button 
            class="operation-btn" 
            @click="performOperation('average')"
            :class="{ 'active': activeOperation === 'average' }"
            :disabled="isLoading"
          >
            求平均值
          </button>
        </div>
        
        <div class="computation-animation" v-if="isComputing">
          <div class="animation-container">
            <div class="computation-particles"></div>
            <div class="computation-text">{{ computationText }}</div>
          </div>
        </div>
      </div>
      
      <!-- 右侧结果区 -->
      <div class="result-section">
        <h2>计算结果</h2>
        <div class="result-container">
          <div class="result-content" v-if="hasResult">
            <div class="result-type">{{ resultType }}</div>
            <div class="result-value" :class="resultClass">{{ resultValue }}</div>
            <div class="result-explanation">{{ resultExplanation }}</div>
          </div>
          <div class="placeholder-text" v-if="!hasResult">
            <p>请在加密数据上选择一个操作</p>
          </div>
        </div>
        
        <button 
          class="btn btn-secondary verify-btn" 
          @click="verifyResult"
          v-if="hasResult"
          :disabled="isLoading"
        >
          验证结果
        </button>
        
        <div class="verification-panel" v-if="showVerification">
          <h3>验证信息</h3>
          <div class="verification-content">
            <div class="verification-row">
              <div class="verification-label">明文计算:</div>
              <div class="verification-value">{{ verificationPlaintext }}</div>
            </div>
            <div class="verification-row">
              <div class="verification-label">密文计算:</div>
              <div class="verification-value">{{ verificationCiphertext }}</div>
            </div>
            <div class="verification-status" :class="verificationMatch ? 'success' : 'error'">
              {{ verificationMatch ? '✓ 验证通过' : '✗ 验证失败' }}
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <div class="demo-info">
      <h2>关于本演示</h2>
      <p>本演示展示了全同态加密的基本原理和应用场景。在实际应用中，全同态加密可以保护敏感数据的隐私，同时允许在加密数据上进行计算操作。</p>
      <p>技术说明：</p>
      <ul>
        <li>本演示使用了微软SEAL库的Python封装TenSEAL实现</li>
        <li>支持的操作包括比较大小、加法和平均值计算</li>
        <li>实际的全同态加密系统会使用更复杂的参数设置和优化</li>
      </ul>
      <p>了解更多关于全同态加密的技术细节，请访问<router-link to="/algorithms">算法原理</router-link>页面。</p>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue';

// API 基础URL
const API_BASE_URL = 'http://localhost:5000/api';

// 会话ID
const sessionId = ref('');

// 输入数据
const inputA = ref('');
const inputB = ref('');
const isEncrypted = ref(false);
const encryptedA = ref('');
const encryptedB = ref('');

// 加载状态
const isLoading = ref(false);

// 计算状态
const isComputing = ref(false);
const computationText = ref('');
const activeOperation = ref('');
const highlightA = ref(false);
const highlightB = ref(false);

// 结果状态
const hasResult = ref(false);
const resultType = ref('');
const resultValue = ref('');
const resultExplanation = ref('');
const resultClass = ref('');

// 验证状态
const showVerification = ref(false);
const verificationPlaintext = ref('');
const verificationCiphertext = ref('');
const verificationMatch = ref(true);

// 计算输入是否有效
const canEncrypt = computed(() => {
  return inputA.value !== '' && inputB.value !== '';
});

// 在组件挂载时创建会话
onMounted(async () => {
  await createSession();
});

// 创建加密会话
async function createSession() {
  try {
    isLoading.value = true;
    const response = await fetch(`${API_BASE_URL}/create_session`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({})
    });
    
    const data = await response.json();
    
    if (data.success) {
      sessionId.value = data.session_id;
    } else {
      console.error('创建会话失败:', data.error);
      alert('创建加密会话失败，请刷新页面重试');
    }
  } catch (error) {
    console.error('API请求错误:', error);
    alert('连接服务器失败，请确保后端服务正在运行');
  } finally {
    isLoading.value = false;
  }
}

// 加载示例数据
function loadSampleData() {
  inputA.value = '3500';
  inputB.value = '2800';
}

// 加密数据
async function encryptData() {
  if (!canEncrypt.value || !sessionId.value) return;
  
  try {
    isLoading.value = true;
    
    const response = await fetch(`${API_BASE_URL}/encrypt`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        session_id: sessionId.value,
        value_a: inputA.value,
        value_b: inputB.value
      })
    });
    
    const data = await response.json();
    
    if (data.success) {
      encryptedA.value = data.encrypted_a;
      encryptedB.value = data.encrypted_b;
      isEncrypted.value = true;
    } else {
      console.error('加密失败:', data.error);
      alert('加密数据失败: ' + data.error);
    }
  } catch (error) {
    console.error('API请求错误:', error);
    alert('连接服务器失败，请确保后端服务正在运行');
  } finally {
    isLoading.value = false;
  }
}

// 执行操作
async function performOperation(operation) {
  if (!isEncrypted.value || !sessionId.value) return;
  
  activeOperation.value = operation;
  isComputing.value = true;
  hasResult.value = false;
  showVerification.value = false;
  isLoading.value = true;
  
  // 根据操作类型设置计算文本
  switch (operation) {
    case 'compare':
      computationText.value = '比较加密数值大小...';
      break;
    case 'add':
      computationText.value = '执行加密加法运算...';
      break;
    case 'average':
      computationText.value = '计算加密数值平均值...';
      break;
  }
  
  // 模拟计算动画
  await simulateComputation(operation);
  
  try {
    const response = await fetch(`${API_BASE_URL}/compute`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        session_id: sessionId.value,
        operation: operation
      })
    });
    
    const data = await response.json();
    
    if (data.success) {
      hasResult.value = true;
      resultType.value = data.result_type;
      resultValue.value = data.result;
      resultExplanation.value = data.explanation;
      resultClass.value = `${operation}-result`;
    } else {
      console.error('计算失败:', data.error);
      alert('执行加密计算失败: ' + data.error);
    }
  } catch (error) {
    console.error('API请求错误:', error);
    alert('连接服务器失败，请确保后端服务正在运行');
  } finally {
    isComputing.value = false;
    isLoading.value = false;
  }
}

// 模拟计算过程的动画
async function simulateComputation(operation) {
  // 重置高亮状态
  highlightA.value = false;
  highlightB.value = false;
  
  // 模拟计算动画
  if (operation === 'compare') {
    await sleep(500);
    highlightA.value = true;
    await sleep(800);
    highlightA.value = false;
    highlightB.value = true;
    await sleep(800);
    highlightA.value = true;
  } else {
    await sleep(500);
    highlightA.value = true;
    highlightB.value = true;
    await sleep(1000);
  }
  
  // 计算完成后
  await sleep(500);
  highlightA.value = false;
  highlightB.value = false;
}

// 验证结果
async function verifyResult() {
  if (!hasResult.value || !sessionId.value) return;
  
  isLoading.value = true;
  
  try {
    const response = await fetch(`${API_BASE_URL}/verify`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        session_id: sessionId.value,
        operation: activeOperation.value
      })
    });
    
    const data = await response.json();
    
    if (data.success) {
      showVerification.value = true;
      verificationPlaintext.value = data.plaintext_result;
      verificationCiphertext.value = resultValue.value;
      verificationMatch.value = data.match;
    } else {
      console.error('验证失败:', data.error);
      alert('验证结果失败: ' + data.error);
    }
  } catch (error) {
    console.error('API请求错误:', error);
    alert('连接服务器失败，请确保后端服务正在运行');
  } finally {
    isLoading.value = false;
  }
}

// 重置演示
async function resetDemo() {
  inputA.value = '';
  inputB.value = '';
  isEncrypted.value = false;
  encryptedA.value = '';
  encryptedB.value = '';
  isComputing.value = false;
  activeOperation.value = '';
  hasResult.value = false;
  showVerification.value = false;
  highlightA.value = false;
  highlightB.value = false;
  
  // 创建新会话
  await createSession();
}

// 工具函数：延迟
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
</script>

<style scoped>
.demo-view {
  max-width: 1200px;
  margin: 0 auto;
  padding: 2rem 1rem;
}

.page-title {
  text-align: center;
  margin-bottom: 1rem;
}

.page-description {
  text-align: center;
  max-width: 800px;
  margin: 0 auto 3rem;
  color: var(--text-secondary);
}

.demo-container {
  display: grid;
  grid-template-columns: 1fr 1.5fr 1fr;
  gap: 2rem;
  margin-bottom: 3rem;
  min-height: 500px;
}

/* 输入区样式 */
.input-section,
.computation-section,
.result-section {
  background-color: var(--card-bg);
  border-radius: 8px;
  padding: 1.5rem;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
}

.input-section h2,
.computation-section h2,
.result-section h2 {
  margin-bottom: 1.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border-color);
}

.input-group {
  margin-bottom: 1.5rem;
}

.input-with-icon {
  position: relative;
}

.lock-icon {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 1.2rem;
}

.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: auto;
}

/* 计算区样式 */
.encrypted-data-container {
  flex: 1;
  background-color: var(--footer-bg);
  border-radius: 6px;
  padding: 1rem;
  margin-bottom: 1.5rem;
  overflow: auto;
  font-family: 'Roboto Mono', monospace;
  font-size: 0.9rem;
}

.encrypted-data {
  margin-bottom: 1rem;
}

.data-label {
  color: var(--text-secondary);
  margin-bottom: 0.25rem;
}

.data-value {
  padding: 0.5rem;
  background-color: var(--bg-color);
  border-radius: 4px;
  word-break: break-all;
  transition: background-color 0.3s, box-shadow 0.3s;
}

.data-value.active {
  background-color: rgba(41, 98, 255, 0.1);
  box-shadow: 0 0 0 2px var(--primary-color);
}

.placeholder-text {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--text-light);
  text-align: center;
}

.operation-buttons {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.operation-btn {
  flex: 1;
  padding: 0.75rem 0.5rem;
  background-color: var(--footer-bg);
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
  font-weight: 500;
}

.operation-btn:hover {
  background-color: var(--hover-bg);
}

.operation-btn.active {
  background-color: var(--primary-color);
  color: white;
}

.computation-animation {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.animation-container {
  position: relative;
  width: 100%;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.computation-particles {
  position: absolute;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(41, 98, 255, 0.2), transparent);
  background-size: 200% 100%;
  animation: shimmer 2s infinite;
}

.computation-text {
  position: relative;
  z-index: 1;
  font-weight: 500;
  color: var(--primary-color);
}

/* 结果区样式 */
.result-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.5rem;
}

.result-content {
  text-align: center;
  width: 100%;
}

.result-type {
  font-weight: 500;
  margin-bottom: 0.5rem;
  color: var(--text-secondary);
}

.result-value {
  font-size: 2rem;
  font-weight: 700;
  margin-bottom: 1rem;
  padding: 1rem;
  border-radius: 8px;
  animation: fadeIn 0.5s;
}

.compare-result {
  background-color: rgba(33, 150, 243, 0.1);
  color: var(--info-color);
}

.add-result {
  background-color: rgba(76, 175, 80, 0.1);
  color: var(--success-color);
}

.average-result {
  background-color: rgba(156, 39, 176, 0.1);
  color: #9c27b0;
}

.result-explanation {
  color: var(--text-secondary);
}

.verify-btn {
  width: 100%;
}

.verification-panel {
  margin-top: 1.5rem;
  padding: 1rem;
  background-color: var(--footer-bg);
  border-radius: 6px;
  animation: slideDown 0.3s;
}

.verification-panel h3 {
  margin-bottom: 1rem;
  font-size: 1rem;
}

.verification-row {
  display: flex;
  margin-bottom: 0.75rem;
}

.verification-label {
  flex: 1;
  font-weight: 500;
}

.verification-value {
  flex: 2;
  font-family: 'Roboto Mono', monospace;
}

.verification-status {
  text-align: center;
  padding: 0.5rem;
  border-radius: 4px;
  font-weight: 500;
  margin-top: 1rem;
}

.verification-status.success {
  background-color: rgba(76, 175, 80, 0.1);
  color: var(--success-color);
}

.verification-status.error {
  background-color: rgba(244, 67, 54, 0.1);
  color: var(--error-color);
}

/* 演示信息区域 */
.demo-info {
  background-color: var(--footer-bg);
  padding: 2rem;
  border-radius: 8px;
}

.demo-info h2 {
  margin-bottom: 1rem;
}

.demo-info p {
  margin-bottom: 1rem;
}

.demo-info ul {
  margin-bottom: 1rem;
  padding-left: 1.5rem;
}

.demo-info li {
  margin-bottom: 0.5rem;
}

/* 动画 */
@keyframes shimmer {
  0% {
    background-position: -100% 0;
  }
  100% {
    background-position: 100% 0;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 响应式设计 */
@media (max-width: 1024px) {
  .demo-container {
    grid-template-columns: 1fr 1fr;
  }
  
  .result-section {
    grid-column: span 2;
  }
}

@media (max-width: 768px) {
  .demo-container {
    grid-template-columns: 1fr;
  }
  
  .result-section {
    grid-column: span 1;
  }
}
</style>